using System;
using CoreTypes;
using System.Linq;
using System.Custom;
using CustomControls;
using System.Drawing;
using System.Diagnostics;
using System.Custom.Window;
using System.Windows.Forms;
using MainModule.Properties;
using System.ComponentModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace MainModule
{
   public partial class MainWindow : Window, IMainWindow
   {
      #region Window Data

      int FFloatingMoveDelta;
      bool FCreateSessionView;// = true;
      bool FComposeContactsDenied;
      int FDockTimerControlInterval = 200;
      int FDockTimerAnimationInterval = 1;

      Font FLabelFont;
      Font FLabelFontU;
      Padding FPadding;
      Timer FDockingTimer;
      Collection<PresenceNotification> FSignedOnNotifications;
      Image FDropDownArrowImage1 = ResourceWrapper.GetImage("DropDownArrow");
      Image FDropDownArrowImage2 = ResourceWrapper.GetImage("DropDownArrow2");

      static InternetCommunicator FCommunicator = InternetCommunicator.Self;

      #endregion

      #region MainWindow Initializers

      public MainWindow()
      {
         InitializeComponent();

         SuspendLayout();

         foreach (var typeInfo in FCommunicator.SupportedMediaSessionTypes) AddCreateSessionMenuItem(typeInfo.Value);

         FCommunicator.LogonState += OnLogonState;
         FCommunicator.PresenceNotified += OnPresenceNotified;
         FCommunicator.SyncContactsState += OnSyncContactsState;
         FCommunicator.AccountAdded += communicator_AccountAdded;
         FCommunicator.ProfileLoaded += communicator_ProfileLoaded;
         FCommunicator.StatusChanged += communicator_StatusChanged;
         FCommunicator.ChatMessageReceived += OnChatMessageReceived;
         FCommunicator.NotifyPresenceState += OnNotifyPresenceState;
         FCommunicator.AccountRemoved += communicator_AccountRemoved;
         FCommunicator.ContactsLoaded += communicator_ContactsLoaded;
         FCommunicator.ContactsChanged += communicator_ContactsChanged;
         FCommunicator.PropertyChanged += communicator_PropertyChanged;
         FCommunicator.RequestUserInfoState += OnRequestUserInfoState;
         FCommunicator.MessageAccepted += communicator_MessageAccepted;
         FCommunicator.MediaSessionCreated += communicator_MediaSessionCreated;
         FCommunicator.CurrentAccountChanged += communicator_CurrentAccountChanged;
         FCommunicator.MediaSessionTypeAdded += communicator_MediaSessionTypeAdded;

         Settings.Default.PropertyChanged += settings_PropertyChanged;

         FSignedOnNotifications = new Collection<PresenceNotification>();

         FDockingTimer = new Timer();
         FDockingTimer.Interval = FDockTimerControlInterval;
         FDockingTimer.Tick += (s, e) => { DoDockingAnimation(true); };

         menuSessions.Paint += menu_Paint;
         itemSystemTheme.Click += itemTheme_Click;
         itemSystemTheme.MouseEnter += itemTheme_MouseEnter;

         menuThemes.Paint += (object sender, PaintEventArgs e) =>
         {
            foreach (ToolStripMenuItem item in menuThemes.Items)
            {
               ColorTheme theme = item.Tag as ColorTheme;
               FCommunicator.DrawTheme(theme, e.Graphics, item.Bounds, ColorThemeObject.MenuItem);
            }
            menuThemes.Tag = sender;
         };

         foreach (var theme in InternetCommunicator.Self.ColorThemes)
         {
            ToolStripMenuItem item = new ToolStripMenuItem(theme.Name);

            item.Name = theme.Name;
            item.Tag = theme;
            item.Click += itemTheme_Click;
            item.MouseEnter += itemTheme_MouseEnter;

            menuThemes.Items.Add(item);
         }
         foreach (ColorFillStyle type in Enum.GetValues(typeof(ColorFillStyle)))
         {
            if (type == ColorFillStyle.Plastic || type == ColorFillStyle.Glass)
            {
               ToolStripMenuItem item = new ToolStripMenuItem(type.ToString());

               item.Tag = type;
               item.Name = type.ToString();

               item.MouseEnter += (object sender, EventArgs e) =>
               {
                  InternetCommunicator.Self.ColorFillStyle = (ColorFillStyle)(sender as ToolStripMenuItem).Tag;
               };
               item.Click += (object sender, EventArgs e) =>
               {
                  Settings.Default.ColorFillStyle = (ColorFillStyle)(sender as ToolStripMenuItem).Tag;
               };

               menuFillStyles.Items.Add(item);
            }
         }

         ColorTheme = FCommunicator.ColorTheme;
         RenderMode = FCommunicator.RenderMode;

         FComposeContactsDenied = true;
         itemShowGroups.Checked = Settings.Default.ShowGroups;
         itemShowHiddenContacts.Checked = Settings.Default.ShowHiddenContacts;
         itemShowOfflineContacts.Checked = Settings.Default.ShowOfflineContacts;
         FComposeContactsDenied = false;

         FLabelFont = new Font(labelAccount.Font, FontStyle.Regular);
         FLabelFontU = new Font(labelAccount.Font, FontStyle.Underline);

         AdjustToolbarButtons();
         UpdatewWindowView();

         ToggleAccountBar(Settings.Default.ShowAccountBar, false);
         Icon = Icon.FromHandle(ResourceWrapper.GetImage("CitronIcon2_16").GetHicon());

         itemAccount.DropDown = InternetCommunicator.Self.Components.menuAccount;
         menuItemPersonal.DropDown = InternetCommunicator.Self.Components.menuAccount;
         
         OrganizeProfileView();

         ResumeLayout(true);
      }
      protected override void OnFileDialogVisibleChanged(object sender, EventArgs e)
      {
         if (Shell.FileDialogVisible)
         {
            FInteractiveState = Visible;
            if (Visible) Hide();
         }
         else
         {
            Visible = FInteractiveState;
         }
      }

      #endregion

      #region IVisualRegion Members

      public override void Visualize()
      {
         Opacity = 1.00;
         Show();

         // Code for floating panel bug reduse
         //SuspendLayout();

         //Opacity = 0.10;
         //Visible = true;
         //Opacity = 1.00;
         ////Opacity = 0.92;

         //ResumeLayout(true);
      }

      #endregion

      #region MainWindow Members

      private bool WindowBorders
      {
         get
         {
            return FormBorderStyle != FormBorderStyle.None;
         }
         set
         {
            TopMost = Settings.Default.MainWindowLayout == WindowDockType.FloatPanel;
            ControlBox = Settings.Default.MainWindowLayout != WindowDockType.FloatPanel;

            if (value)
            {
               FPadding.All = 0;
               FormBorderStyle = FormBorderStyle.Sizable;
            }
            else
            {
               FPadding.Top = 0;
               FPadding.Bottom = 1;
               FormBorderStyle = FormBorderStyle.None;
               FPadding.Left = Settings.Default.MainWindowLeftSide ? 1 : 2;
               FPadding.Right = !Settings.Default.MainWindowLeftSide ? 1 : 2;
            }
            Padding = FPadding;
            AdjustControlsGeometry();
         }
      }
      internal bool ShowAccountBar
      {
         get
         {
            return panelAccountBar.Height > 0;
         }
         set
         {
            itemShowAccountBar.Checked = value;

            ToggleAccountBar(value, true);
         }
      }
      private bool IsFloatingPanelHidden
      {
         get
         {
            return Settings.Default.MainWindowLeftSide ? Location.X == -Width :
                                                         Location.X == Screen.PrimaryScreen.WorkingArea.Width;
         }
      }
      internal ContextMenuStrip MainMenu
      {
         get
         {
            return menuMain;
         }
      }

      private void ShowSignedOn()
      {
         IEnumerable<Contact> contacts = FSignedOnNotifications.Select(n => n.Sender as Contact);

         IEnumerable<ItemView> views = contacts.Select(c => GetContactsView(c.Owner)).Distinct().Where(v => v != null);

         foreach (ItemView view in views)
         {
            if (FSignedOnNotifications.Count == 1)
            {
               Contact contact = contacts.ElementAt(0);

               DataItem item = view[contact.Identifier];

               if (item != null) view.RemoveItem(item, true, null);

               AddContactToView(view, contact);

               UpdateContactGroups(view, contact.Groups);
            }
            else if (FSignedOnNotifications.Count > 1)
            {
               if (Settings.Default.ShowOfflineContacts)
               {
                  foreach (Contact contact in contacts)
                  {
                     DataItem item = view[contact.Identifier];

                     if (item != null)
                     {
                        UpdateDataItem(item);

                        DelayedAction.Do(view, () => view.Sort(), 2500, true);
                     }
                     UpdateContactGroups(view, contact.Groups);
                  }
               }
               else
               {
                  view.BeginUpdate();
                  view.HideView();

                  try
                  {
                     foreach (Contact contact in contacts)
                     {
                        AddContactToView(view, contact);

                        UpdateContactGroups(view, contact.Groups);
                     }
                  }
                  finally
                  {
                     view.EndUpdate();
                     view.ShowView();
                  }
               }
            }
         }
         FSignedOnNotifications.Clear();
      }
      private void DockAsFloatPanel()
      {
         Hide();

         WindowBorders = false;
         Bounds = GetDefaultWindowRect();

         Show();

         FDockingTimer.Enabled = true;

         ShowInTaskbar = false;
      }
      private void DockAsNormalWindow()
      {
         SuspendLayout();

         WindowBorders = true;
         Bounds = GetDefaultWindowRect();

         ResumeLayout();

         FDockingTimer.Enabled = false;

         ShowInTaskbar = Settings.Default.MainWindowLayout == WindowDockType.ClassicWindowLarge;
      }
      private void OrganizeProfileView()
      {
         foreach (ToolStripItem item in menuProfile.Items)
         {
            if (item.Tag != null)
            {
               menuProfile.Items.Remove(item);
               item.Dispose();
            }
         }
         foreach (Account account in FCommunicator.ActiveAccounts)
         {
            ToolStripMenuItem item = new ToolStripMenuItem(account.ToString(InfoStrings.NameServiceStatus), null, itemSelectAccount_Click, account.Identifier);
            menuProfile.Items.Insert(0, item);
            item.Checked = account == FCommunicator.CurrentAccount;
            item.Tag = account;
         }
         ShowAccount(FCommunicator.CurrentAccount);
      }
      private void AdjustToolbarButtons()
      {
         buttonProfile.AutoSize = false;
         buttonProfile.Width = 33;
         buttonProfile.ShowDropDownArrow = false;
         buttonProfile.Height = toolStripTop.Height - 5;
         buttonProfile.DisplayStyle = ToolStripItemDisplayStyle.None;

         buttonContactList.AutoSize = false;
         buttonContactList.Width = buttonProfile.Width;
         buttonContactList.ShowDropDownArrow = false;
         buttonContactList.Height = buttonProfile.Height;
         buttonContactList.DisplayStyle = ToolStripItemDisplayStyle.None;

         buttonMenu.AutoSize = false;
         buttonMenu.Width = 33;
         buttonMenu.ShowDropDownArrow = false;
         buttonMenu.Height = buttonProfile.Height;
         buttonMenu.DisplayStyle = ToolStripItemDisplayStyle.None;

         buttonServiceMenu.AutoSize = false;
         buttonServiceMenu.Width = buttonProfile.Width;
         buttonServiceMenu.ShowDropDownArrow = false;
         buttonServiceMenu.Height = buttonProfile.Height;
         buttonServiceMenu.DisplayStyle = ToolStripItemDisplayStyle.None;

         buttonPresence.AutoSize = false;
         buttonPresence.Width = 33;
         buttonPresence.ShowDropDownArrow = false;
         buttonPresence.Height = buttonProfile.Height;
         buttonPresence.DisplayStyle = ToolStripItemDisplayStyle.None;

         toolStripTop.Margin = new Padding(2, 2, 1, 3);
      }
      private void AdjustControlsGeometry()
      {
         int lrPadding = RenderMode == ToolStripRenderMode.Professional ? 2 : 1;

         toolStripBottom.Padding = IsThemeActive ?
            new Padding((FormBorderStyle == FormBorderStyle.None ? 0 : lrPadding), (RenderMode == ToolStripRenderMode.System ? 1 : 2), lrPadding, 3) :
            new Padding(0, 2, 1, (RenderMode == ToolStripRenderMode.System ? 4 : 3));

         toolStripTop.Padding = toolStripBottom.Padding;

         if (FormBorderStyle == FormBorderStyle.None)
         {
            itemViewControl.AllBorderWidth = 1;
            panelAccountBar.Padding = new Padding(1, 1, 1, 0);
            //panelLayoutInfoBar.Padding = IsThemeActive && RenderMode == ToolStripRenderMode.Professional ? new Padding(1, 0, 1, 0) : new Padding(1, 1, 1, 0);
         }
         else
         {
            panelAccountBar.Padding = IsThemeActive ? new Padding(0, 1, 0, 0) : new Padding(1, 1, 1, 0);

            if (IsThemeActive)
            {
               itemViewControl.TopBorderWidth = 1;
               itemViewControl.LeftBorderWidth = 0;
               itemViewControl.RightBorderWidth = 0;
               itemViewControl.BottomBorderWidth = 1;
            }
            else
            {
               itemViewControl.TopBorderWidth = 1;
               itemViewControl.LeftBorderWidth = 1;
               itemViewControl.RightBorderWidth = 1;
               itemViewControl.BottomBorderWidth = 1;
            }
            //tableLayoutMainView.Padding = IsThemeActive ? new Padding(0, 1, 0, 1) : new Padding(1, 1, 1, 1);
            //panelLayoutInfoBar.Padding = IsThemeActive ? new Padding(0, RenderMode == ToolStripRenderMode.Professional ? 0 : 1, 0, 0) : new Padding(1, 1, 1, 0);
         }
         Padding p = statusBarLabel.Margin;
         if (Computer.OSPlatform == OS.VistaOrLater)
         {
            p.Top = 2;
            p.Bottom = 1;
         }
         else
         {
            p.Top = 1;
            p.Bottom = 0;
         }
         statusBarLabel.Margin = p;
         tableLayoutMainView.Padding = new Padding(0);
      }
      private string GetContactsCountStat()
      {
         return FCommunicator.CurrentAccount.OnlineContacts.Count() + "/" +
                FCommunicator.CurrentAccount.Contacts.Count() +
                (FCommunicator.ActiveAccounts.Count == 1 ? "" : " - " +
                FCommunicator.ActiveAccounts.Sum(a => a.OnlineContacts.Count()) + "/" +
                FCommunicator.ActiveAccounts.Sum(a => a.Contacts.Count()));
      }
      private void UpdateContactsViewHeader()
      {
         ItemView view = GetContactsView(null);

         if (view != null)
         {
            view.Caption = GetContactsCountStat();

            DelayedAction.Do(this, () =>
            {
               view = GetContactsView(null);
               if (view != null) view.Caption = ResourceWrapper.GetString("S_My_contacts");
            },
            2500, true);
         }
      }
      private Rectangle GetDefaultWindowRect()
      {
         Rectangle r = new Rectangle();
         Rectangle area = Screen.PrimaryScreen.WorkingArea;

         int baseWidth = Computer.OSPlatform == OS.VistaOrLater ? 210 : 200;

         switch (Settings.Default.MainWindowLayout)
         {
            case WindowDockType.ClassicWindowNormal:
            {
               r.Width = baseWidth + 20;
               r.Height = (int)(area.Height * 0.93);
               r.Y = area.Height - r.Height;
               r.X = Settings.Default.MainWindowLeftSide ?
                    (FCommunicator.InstanceNumber > 0 ? FCommunicator.InstanceNumber - 1 : 0) * r.Width :
                     area.Width - r.Width;
               break;
            }
            case WindowDockType.ClassicWindowLarge:
            {
               r.Y = 0;
               r.Width = baseWidth + 45;
               r.Height = (int)(area.Height * 0.97);
               r.Y = area.Height - r.Height;
               r.X = Settings.Default.MainWindowLeftSide ? 0 : area.Width - r.Width;
               break;
            }
            case WindowDockType.FloatPanel:
            {
               r.Y = 0;
               r.Width = baseWidth;
               r.Height = area.Height;
               r.X = Settings.Default.MainWindowLeftSide ? -r.Width : Screen.PrimaryScreen.WorkingArea.Width;
               break;
            }
         }

         return r;
      }
      private void ShowAccount(Account account)
      {
         Text = FCommunicator.Title + " - " + account.CustomName;//.ToString(InfoStrings.NameService);

         labelStatusMessage.Text = account.StatusMessage;
         itemAccount.Text = account.ToString(InfoStrings.NameService);
         //itemAccount.Text = Resources.S_Manage_account.Replace("<account>", account.CustomName);
         labelAccount.Text = account.CustomName + (ShowAccountBar ? ":" : "...");
         labelAccountName.Text = account.ToString(InfoStrings.ServiceLogin);

         while (TextRenderer.MeasureText(itemAccount.Text, itemAboutUs.Font).Width < 125) itemAccount.Text += " ";

         if (panelUserpic.BackgroundImage != null) panelUserpic.BackgroundImage.Dispose();
         panelUserpic.BackgroundImage = account.Info.HasUserpic ? account.Info.Userpic : FCommunicator.DefaultUserpic;

         string viewName = account.Identifier + "_Contacts";
         ItemView view = itemViewControl[viewName];

         if (view == null)
         {
            DelayedAction.Do(() =>
            {
               ComposeContactsView(account);
               view = itemViewControl.SelectEntry("Contacts", viewName);
            },
            100);
         }
         else
         {
            view = itemViewControl.SelectEntry("Contacts", viewName);
         }

         itemServiceMenu.Text = account.ServiceConfig.ToString() + " " + Resources.S_Service.ToLower();
         itemServiceMenu.DropDown = (account.ServiceDriver as CommunicationServiceObjectBase).Menu;
         buttonServiceMenu.DropDown = itemServiceMenu.DropDown;

         communicator_StatusChanged(this, null);
      }
      private void UpdateDataItem(DataItem item)
      {
         try
         {
            item.View.BeginUpdate(item);

            if (item.IsGroup)
            {
               ContactGroup group = item[typeof(ContactGroup)] as ContactGroup;
               int totalInGroup = group.Owner.Contacts.Count(c => Settings.Default.ShowGroups ? c.Groups.Contains(group) : true);
               int onlineInGroup = group.Owner.OnlineContacts.Count(c => Settings.Default.ShowGroups ? c.Groups.Contains(group) : true);
               item.Comment = "(" + onlineInGroup + "/" + totalInGroup + ")";
               item.Text = group.Name;
            }
            else
            {
               Contact contact = item[typeof(Contact)] as Contact;
               
               FCommunicator.RetrieveNickIfNecessary(contact);

               Status status = contact.Status;

               item.Text = contact.CustomName;
               item.ImageName = "Status:" + status.Value.ToString();
               item.ExtImageName = contact.Owner.IsVipContact(contact.Identifier) ? "VipUser" :
                                   contact.Owner.IsBlockedContact(contact.Identifier, PrivacyType.All) ? "BlockedUser" : "";
               item.Comment = status.ToShortString();
            }
            item.View.EndUpdate(item);
         }
         catch (Exception error)
         {
            item.View.EndUpdate(item);

            FCommunicator.Log(error, true);
         }
      }
      protected override void UpdatewWindowView()
      {
         itemAboutUs.Text = Resources.S_About + " " + FCommunicator.Title + "...";

         labelStatusMessage_TextChanged(this, null);
         toolStrip_EnabledChanged(menuAppMain, null);
         toolStrip_EnabledChanged(toolStripTop, null);
         toolStrip_EnabledChanged(toolStripBottom, null);
         menuItemProfile.Visible = !toolStripTop.Enabled;

         AdjustControlsGeometry();
      }
      private void SaveExpandedState(ItemView view)
      {
         foreach (DataItem item in view.Items)
         {
            if (item.IsGroup && item[typeof(ContactGroup)] is ContactGroup)
            {
               (item[typeof(ContactGroup)] as ContactGroup).Expanded = item.Expanded;
            }
         }
      }
      internal void DoDockingAnimation(bool byCursor)
      {
         if (Settings.Default.MainWindowLayout != WindowDockType.FloatPanel) return;

         Point location = Location;
         int screenWidth = Screen.PrimaryScreen.WorkingArea.Width;
         int screenHeight = Screen.PrimaryScreen.WorkingArea.Height;

         if (FDockingTimer.Interval == FDockTimerAnimationInterval)
         {
            if (Settings.Default.MainWindowLeftSide)
            {
               if (FFloatingMoveDelta < 0 && location.X < -Width + 25) FFloatingMoveDelta = -1;

               if (FFloatingMoveDelta > 0 && location.X > -30) FFloatingMoveDelta = 1;

               if (FFloatingMoveDelta > 0 && location.X + FFloatingMoveDelta >= 0 ||
                   FFloatingMoveDelta < 0 && location.X + FFloatingMoveDelta == -Width)
               {
                  location.X = FFloatingMoveDelta > 0 ? 0 : -Width;
                  FDockingTimer.Interval = FDockTimerControlInterval;
                  if (location.X == 0)
                  {
                     itemViewControl.Refresh();
                  }
               }
               else
               {
                  location.X += FFloatingMoveDelta;
               }
            }
            else
            {
               if (FFloatingMoveDelta > 0 && location.X > screenWidth - 25) FFloatingMoveDelta = 1;

               if (FFloatingMoveDelta < 0 && location.X < screenWidth - Width + 30) FFloatingMoveDelta = -1;

               if (FFloatingMoveDelta > 0 && location.X + FFloatingMoveDelta >= screenWidth ||
                   FFloatingMoveDelta < 0 && location.X + FFloatingMoveDelta <= screenWidth - Width)
               {
                  location.X = FFloatingMoveDelta > 0 ? screenWidth : screenWidth - Width;
                  FDockingTimer.Interval = FDockTimerControlInterval;
                  if (location.X < screenWidth)
                  {
                     itemViewControl.Refresh();
                  }
               }
               else
               {
                  location.X += FFloatingMoveDelta;
               }
            }
            Location = location;
         }
         else
         {
            if (Settings.Default.MainWindowLeftSide)
            {
               if (!byCursor && IsFloatingPanelHidden || IsFloatingPanelHidden && Cursor.Position.X == 0 && Cursor.Position.Y > 70)
               {
                  Activate();
                  FFloatingMoveDelta = 30;
                  FDockingTimer.Interval = FDockTimerAnimationInterval;
               }
               else if (!IsActive && CanBeDeactivated && !IsFloatingPanelHidden && Cursor.Position.X > Width + 30)
               {
                  FFloatingMoveDelta = -10;
                  FDockingTimer.Interval = FDockTimerAnimationInterval;
               }
            }
            else
            {
               if (!byCursor && IsFloatingPanelHidden || IsFloatingPanelHidden && Cursor.Position.X == Screen.PrimaryScreen.WorkingArea.Width - 1 && Cursor.Position.Y > 70)
               {
                  Activate();
                  FFloatingMoveDelta = -30;
                  FDockingTimer.Interval = FDockTimerAnimationInterval;
               }
               else if (!IsActive && CanBeDeactivated && !IsFloatingPanelHidden && Cursor.Position.X < Screen.PrimaryScreen.WorkingArea.Width - Width - 30)
               {
                  FFloatingMoveDelta = 10;
                  FDockingTimer.Interval = FDockTimerAnimationInterval;
               }
            }
         }
      }
      private void ActivateContactListItem(DataItem item)
      {
         if (item == null) return;

         if (item[typeof(ServiceMessage)] != null)
         {
            FCommunicator.AcceptMessage(item[typeof(ServiceMessage)] as ServiceMessage);
         }
         else if (item[typeof(ChatSession)] != null)
         {
            FCommunicator.ShowMediaSession(item[typeof(ChatSession)] as ChatSession, TargetWindow.Existing);
         }
         else if (item[typeof(Contact)] != null)
         {
            FCommunicator.ShowChatSession(item[typeof(Contact)] as Contact);
         }
      }
      private ItemView ComposeContactsView(Account account)
      {
         string viewName = account.Identifier + "_Contacts";
         ItemView view = itemViewControl[viewName];
         int onCount = account.OnlineContacts.Count();
         int offCount = account.Contacts.Count() - onCount;

         try
         {
            if (view == null)
            {
               view = AddItemView(viewName, ResourceWrapper.GetString("S_My_contacts"), "Contacts", ViewStyle.Tree);
               view.NodeSelectionType = NodeSelectionType.FullRow;
               view.Height = itemViewControl.Height * 3 / 4;
               view.ShowSplitters = false;
               view.Tag = account;
            }
            view.BeginUpdate();
            view.HideView();
            view.Clear();

            if (Settings.Default.ShowGroups)
            {
               IEnumerable<ContactGroup> rootGroups = account.Groups.Where(g => string.IsNullOrEmpty(g.ParentName));

               foreach (ContactGroup group in rootGroups) view.AddGroup(group.Name, "", group.Name, "", "", group);

               foreach (ContactGroup group in account.Groups.Except(rootGroups)) view.AddGroup(group.Name, group.ParentName, group.Name, "", "", group);
            }
            else
            {
               view.AddGroup(account.RootGroup.Name, "", account.RootGroup.Name, "", "", account.RootGroup);
            }
            foreach (Contact contact in account.Contacts)
            {
               if (!Settings.Default.ShowHiddenContacts && !contact.Visible ||
                   !Settings.Default.ShowOfflineContacts && contact.Status.Value == StatusCodes.Offline) continue;

               FCommunicator.RetrieveNickIfNecessary(contact);

               AddContactToView(view, contact);
            }

            view.AllowDrag = Settings.Default.ShowGroups;

            UpdateContactGroups(view, null);

            view.EndUpdate();
         }
         catch
         {
            view.EndUpdate();
            view.ShowView();
         }

         DelayedAction.Do(() =>
         {
            if (Settings.Default.ShowGroups) view.Collapse(null); // does not work without delay
            view.SelectedItem = null;
            view.ShowView();
         },
         10);

         DelayedAction.Do(() =>
         {
            if (Settings.Default.ShowGroups)
            {
               IEnumerable<string> names = account.Groups.Where(g => !g.IsSystem && g.Expanded).Select(g => g.Name);

               if (names.Count() > 0) view.Expand(names);

               //if (names.Count() == 0) names = account.Groups.Count() > 0 ? account.Groups.Where(g => g == account.DefaultGroup).Select(g => g.Name) : null;
               //view.Expand(names); // does not work without delay
            }
            else
            {
               view.Expand(null);
            }
         },
         800);

         return view;
      }
      private void ToggleAccountBar(bool expand, bool animate)
      {
         ControlEffects.Slide(panelAccountBar, expand ? SlideAction.Expand : SlideAction.Collapse, false, animate,
            (action) =>
            {
               panelUserpic.Visible = false;
               itemViewControl.SuspendLayout();
               tableLayoutAccountBar.SuspendLayout();
            },
            (action) =>
            {
               if (action == SlideAction.Expand) panelUserpic.Visible = true;
               itemViewControl.ResumeLayout(true);
               tableLayoutAccountBar.ResumeLayout(true);
               labelAccount.Text = FCommunicator.CurrentAccount.CustomName + (ShowAccountBar ? ":" : "...");
            });
      }
      private void AddContactToView(ItemView view, Contact contact)
      {
         if (!contact.Visible && !Settings.Default.ShowHiddenContacts) return;

         Status status = contact.Status;
         Account account = contact.Owner;

         if (Settings.Default.ShowGroups)
         {
            foreach (ContactGroup group in contact.Groups)
            {
               DataItem item = view.AddItem(contact.Identifier, group.Name, contact.CustomName,
                                             status.ToShortString(), "Status:" + status.Value.ToString(), contact);
               item.Hidden = !contact.Visible;
               item.ExtImageName = contact.Owner.IsVipContact(contact.Identifier) ? "VipUser" :
                                   contact.Owner.IsBlockedContact(contact.Identifier, PrivacyType.All) ? "BlockedUser" : "";
            }
         }
         else
         {
            DataItem item = view.AddItem(contact.Identifier, account.RootGroup.Name, contact.CustomName,
                                           status.ToShortString(), "Status:" + status.Value.ToString(), contact);
            item.Hidden = !contact.Visible;
            item.ExtImageName = contact.Owner.IsVipContact(contact.Identifier) ? "VipUser" :
                                contact.Owner.IsBlockedContact(contact.Identifier, PrivacyType.All) ? "BlockedUser" : "";
         }
      }
      private void AddCreateSessionMenuItem(MediaSessionTypeInfo typeInfo)
      {
         //ToolStripMenuItem menuItem = new ToolStripMenuItem();

         //menuItem.Tag = typeInfo.SessionType;
         //menuItem.Image = typeInfo.Image;
         //menuItem.Text = typeInfo.Caption;
         //menuItem.ImageScaling = ToolStripItemImageScaling.None;
         //menuItem.Click += new EventHandler(newMediaSessionMenuItem_Click);

         //menuCreateSession.Items.Add(menuItem);
      }
      private void UpdateContactGroups(ItemView view, IEnumerable<ContactGroup> groups)
      {
         if (Settings.Default.ShowGroups && groups != null)
         {
            foreach (ContactGroup group in groups)
            {
               DataItem item = view[group.Name];

               if (item != null) UpdateDataItem(item);
            }
         }
         else
         {
            foreach (DataItem item in view.Items.Where(item => item.IsGroup))
            {
               UpdateDataItem(item);
            }
         }
      }
      private ItemView AddItemView(string name, string caption, string group, ViewStyle style)
      {
         ItemView view = itemViewControl.AddItemView(name, caption, group, style);

         view.AllowDelete = true;
         view.AllowRemove = false;
         view.Font = itemViewControl.Font;
         view.Margin = new Padding(0, 1, 0, 0);
         view.SmallImageList = FCommunicator.ContactsViewImages;
         view.MouseDown += new MouseEventHandler(view_MouseDown);
         view.HeaderPaint += new EventHandler<PaintEventArgs>(view_HeaderPaint);
         view.ItemHover += new EventHandler<ItemViewBasicEventArgs>(view_ItemHover);
         view.ItemMoved += new EventHandler<ItemViewMovedEventArgs>(view_ItemMoved);
         view.ItemMoving += new EventHandler<ItemViewMovingEventArgs>(view_ItemMoving);
         view.ItemsCompare += new EventHandler<ItemsCompareEventArgs>(view_ItemsCompare);
         view.ItemSelected += new EventHandler<ItemViewBasicEventArgs>(view_ItemSelected);
         view.ItemActivated += new EventHandler<ItemViewBasicEventArgs>(view_ItemActivated);
         view.ItemRemoving += new EventHandler<ItemViewRemovingEventArgs>(view_ItemRemoving);
         view.ItemContextMenu += new EventHandler<ItemViewBasicEventArgs>(view_ItemContextMenu);
         view.ItemExpanded += new EventHandler<ItemViewExpandedCollapsedEventArgs>(view_ItemExpandedCollapsed);
         view.ItemCollapsed += new EventHandler<ItemViewExpandedCollapsedEventArgs>(view_ItemExpandedCollapsed);
         view.AddHeaderButton(Resources.DropDownArrow2, (s, e) => { MenuWrapper.ShowMenu(menuContactsView); }, true);
         view.AddHeaderButton(null, (s, e) => { MenuWrapper.ShowMenu(menuProfile); }, false);
         //view.AddHeaderButton(null, null, false);
         view.HeaderMouseClick += (s, e) =>
         {
            if (e.Button == MouseButtons.Right)
            {
               MenuWrapper.ShowMenu(menuContacts);
            }
            else if (view.Caption == ResourceWrapper.GetString("S_My_contacts"))
            {
               UpdateContactsViewHeader();
            }
            else
            {
               view.Caption = ResourceWrapper.GetString("S_My_contacts");
            }
         };

         return view;
      }

      public bool CanBeDeactivated
      {
         get
         {
            return !(FCommunicator.IsTrayMenuVisible ||
                     InternetCommunicator.Self.IsUserpicDialogVisible ||
                     menuProfile.Visible ||
                     menuContacts.Visible ||
                     menuMain.Visible ||
                     menuPresence.Visible ||
                     menuLayout.Visible);
         }
      }
      public override ColorTheme ColorTheme
      {
         get
         {
            return base.ColorTheme;
         }
         set
         {
            base.ColorTheme = value;

            foreach (ToolStripItem item in menuFillStyles.Items)
            {
               if (item.Tag == null) continue;
               (item as ToolStripMenuItem).Checked = item.Name == InternetCommunicator.Self.ColorFillStyle.ToString();
            }
            foreach (ToolStripMenuItem item in menuThemes.Items)
            {
               item.Checked = item.Name == (value != null ? value.Name : "itemSystemTheme");
            }

            Refresh();
            menuMain.Refresh();
            menuOptions.Refresh();
         }
      }
      public override ToolStripRenderMode RenderMode
      {
         get
         {
            return toolStripBottom.RenderMode;
         }
         set
         {
            toolStripBottom.RenderMode = value;
            toolStripTop.RenderMode = value;

            statusBar.RenderMode = value;
            //statusBar.Refresh();

            menuMain.RenderMode = value;
            menuProfile.RenderMode = value;
            menuContacts.RenderMode = value;
            menuOptions.RenderMode = value;
            menuLayout.RenderMode = value;
            menuHelp.RenderMode = value;
            menuCreateSession.RenderMode = value;
            menuPresence.RenderMode = value;
            menuGlobalPresence.RenderMode = value;
            menuAppMain.RenderMode = value;
            menuRenderMode.RenderMode = value;
            menuThemes.RenderMode = value;
            menuView.RenderMode = value;
            menuFillStyles.RenderMode = value;
            menuContactsView.RenderMode = value;
            menuSessions.RenderMode = value;

            if (value == ToolStripRenderMode.Professional)
            {
               itemRenderModeOffice2003.Checked = true;
               itemRenderModeSystem.Checked = false;
            }
            else
            {
               itemRenderModeOffice2003.Checked = false;
               itemRenderModeSystem.Checked = true;
            }

            AdjustControlsGeometry();
         }
      }
      public ItemView GetContactsView(Account owner)
      {
         if (owner == null) owner = FCommunicator.CurrentAccount;

         return itemViewControl[owner.Identifier + "_Contacts"];
      }

      #endregion

      #region ICommunicationEventHanldlerObject Members

      public void OnPresenceNotified(object sender, MessagingOperationEventArgs e)
      {
         PresenceNotification pn = e.EventMessage as PresenceNotification;

         Contact contact = (Contact)pn.Sender;
         Account account = (Account)pn.Recipient;
         ItemView view = GetContactsView(account);

         if (view == null || account.ContactsState != ContactsState.StatusUpdated) return;

         if (contact.SignedOn)
         {
            FSignedOnNotifications.Add(pn);

            DelayedAction.Putoff(view, 2500); // put off sorting

            DelayedAction.Do(FSignedOnNotifications, () => ShowSignedOn(), 2000, true);
         }
         else if (contact.SignedOff)
         {
            DataItem item = view[contact.Identifier];

            if (item != null)
            {
               view.BeginUpdate(item);

               UpdateDataItem(item);

               item.Comment = Resources.S_Signed_off_at.Replace("<t>", DateTime.Now.ToShortTimeString());

               view.EndUpdate(item);
            }

            UpdateContactGroups(view, contact.Groups);

            DelayedAction.Do(() =>
            {
               // Check all vars again because of long async period:

               item = view[contact.Identifier];

               if (item != null && contact.SignedOff)
               {
                  view.RemoveItem(item, true, null);

                  if (Settings.Default.ShowOfflineContacts) AddContactToView(view, contact);
               }
            },
            10 * 1000);
         }
         else
         {
            DataItem item = view[contact.Identifier];

            if (item != null) UpdateDataItem(item);
         }
      }
      public void OnChatMessageReceived(object sender, MessagingOperationEventArgs e)
      {
         DataItem item = itemViewControl[e.EventMessage.Recipient.Identifier + "_Contacts", e.EventMessage.Sender.Identifier];

         if (item == null) return;

         if (e.EventMessage.Action == ServiceActions.TXTMSG)
         {
            if (!FCommunicator.IsMessageAccepted(e.EventMessage))
            {
               item[typeof(ServiceMessage)] = e.EventMessage;

               item.ImageName = "Envelope";
               item.Comment = (" - " + Resources.S_Count_unread).Replace("<count>", FCommunicator.UnacceptedMessages.Count(msg => msg.Sender == e.EventMessage.Sender).ToString());
            }
         }
      }
      public void OnSendChatMessageState(object sender, MessagingOperationEventArgs e)
      {
      }
      public void OnSendAcknowledgeState(object sender, MessagingOperationEventArgs e)
      {
      }
      public void OnAcknowledgeReceived(object sender, MessagingOperationEventArgs e)
      {
      }
      public void OnUpdateChatMessageState(object sender, MessagingOperationEventArgs e)
      {
      }
      public void OnChatMessageUpdateReceived(object sender, MessagingOperationEventArgs e)
      {
      }
      public void OnSendInvitationState(object sender, MessagingOperationEventArgs e)
      {
      }
      public void OnInvitationReceived(object sender, MessagingOperationEventArgs e)
      {
      }
      public void OnSendInvitationReplyState(object sender, MessagingOperationEventArgs e)
      {
      }
      public void OnInvitationReplyReceived(object sender, MessagingOperationEventArgs e)
      {
      }
      public void OnRequestUserInfoState(object sender, NetworkOperationEventArgs e)
      {
         if (e.Error == null && e.State == OperationState.Completed)
         {
            User user = (User)e.GetResult("User", null);

            if (user is Contact)
            {
               IItemView entry = GetContactsView((user as Contact).Owner);
               if (entry == null) return;

               DataItem item = entry[user.Identifier];
               if (item == null) return;

               item.Text = user.CustomName;
            }
            else if (user is Account)
            {
               if (FCommunicator.CurrentAccount == user) ShowAccount(user as Account);
            }
         }
      }
      public void OnSaveAccountDataState(object sender, SaveAccountDataEventArgs e)
      {
      }
      public void OnLoadAccountDataState(object sender, NetworkOperationEventArgs e)
      {
      }
      public void OnSaveMediaSessionState(object sender, SaveMediaSessionEventArgs e)
      {
      }
      public void OnNotifyPresenceState(object sender, NetworkOperationEventArgs e)
      {
         if (e.Account.Status == Status.Offline)
         {
            var view = GetContactsView(e.Account);

            if (view != null)
            {
               if (Settings.Default.ShowGroups)
               {
                  foreach (Contact contact in e.Account.Contacts)
                  {
                     DataItem item = view[contact.Identifier];
                     if (item != null) UpdateDataItem(item);
                  }

                  view.Sort();

                  UpdateContactGroups(view, null);
               }
               else
               {
                  ComposeContactsView(e.Account);
               }
            }
         }
      }
      public void OnMediaSessionUpdated(object sender, MediaSessionUpdateEventArgs e)
      {
      }
      public void OnCreateAccountState(object sender, NetworkOperationEventArgs e)
      {
      }
      public void OnSyncContactsState(object sender, NetworkOperationEventArgs e)
      {
         if (e.State == OperationState.Completed)
         {
            //
         }
      }
      public void OnDropAccountState(object sender, NetworkOperationEventArgs e)
      {
      }
      public void OnSeekUsersState(object sender, NetworkOperationEventArgs e)
      {
      }
      public void OnLogonState(object sender, NetworkOperationEventArgs e)
      {
         if (e.Account == FCommunicator.CurrentAccount)
         {
            if (e.Error != null)
            {
               if (e.Error.ReasonCode != ErrorReasonCode.ExistAlready)
               {
                  statusBarLabel.Text = e.Account.ToString(InfoStrings.NameServiceStatus);
               }
            }
            else
            {
               if (e.State == OperationState.HostLookup ||
                   e.State == OperationState.DataSending)
               {
                  statusBarLabel.Text = Resources.S_Connecting_service.Replace("<service>", e.Account.ServiceConfig.ToString()) + "...";
               }
            }
         }
      }

      #endregion

      #region Form Event Handlers

      private void window_Load(object sender, EventArgs e)
      {
         Visible = false; // Hides Bounds maintenance

         if (Settings.Default.MainWindowLayout == WindowDockType.FloatPanel)
         {
            DockAsFloatPanel();
         }
         else
         {
            Rectangle r = Settings.Default.MainWindowRect; // store locally because next line will reset it

            DockAsNormalWindow();

            if (r.Size.Height > MinimumSize.Height && r.Size.Width > MinimumSize.Width)
            {
               Size = r.Size;
            }
            if (r.Location.X >= 0 && r.Location.Y > 0)
            {
               Location = r.Location;
            }
         }
      }
      private void window_Shown(object sender, EventArgs e)
      {
         Visible = Settings.Default.ShowOnStart || Settings.Default.MainWindowLayout == WindowDockType.FloatPanel;
      }
      private void window_KeyDown(object sender, KeyEventArgs e)
      {
         //e.SuppressKeyPress = true; // Suppress 'beep', do not make this call unconditional - some default keys will not work

         if (e.KeyCode == Keys.Enter)
         {
            if (textBoxStatusMessage.Focused)
            {
               if (!e.Control)
               {
                  e.SuppressKeyPress = true;
                  textBoxStatusMessage_Leave(null, null);
                  FCommunicator.CurrentAccount.StatusMessage = textBoxStatusMessage.Text.TrimIgnoreNull();
                  Status status = FCommunicator.CurrentAccount.Status;
                  status.Message = FCommunicator.CurrentAccount.StatusMessage;
                  FCommunicator.NotifyPresence(FCommunicator.CurrentAccount, null, status);
                  labelStatusMessage.Text = FCommunicator.CurrentAccount.StatusMessage;
               }
            }
            else
            {
               e.SuppressKeyPress = true;
               ItemView view = GetContactsView(null);
               if (view != null && view.ViewControl.Focused) ActivateContactListItem(view.SelectedItem);
            }
         }
         else if (e.KeyCode == Keys.Escape)
         {
            e.SuppressKeyPress = true;

            if (textBoxStatusMessage.Focused) textBoxStatusMessage_Leave(null, null); else Hide();
         }
         else if (e.KeyCode == Keys.F3)
         {
            e.SuppressKeyPress = true;

            FCommunicator.ShowPeopleSearch(true);
         }
         else if (e.Control && e.KeyCode == Keys.A)
         {
            e.SuppressKeyPress = true;

            if (textBoxStatusMessage.Focused) textBoxStatusMessage.SelectAll(); else FCommunicator.ShowAddContact(null, false);
         }
         else if (e.Control && e.KeyCode == Keys.F)
         {
            e.SuppressKeyPress = true;

            FCommunicator.ShowPeopleSearch(false);
         }
      }
      private void window_NCLMouseDClick(object sender, EventArgs e)
      {
         DockAsNormalWindow();
      }
      private void window_VisibleChanged(object sender, EventArgs e)
      {
         if (!Visible) FCommunicator.MinimizeMemorySize();
      }
      private void window_SystemMenu(object sender, CancelEventArgs e)
      {
         e.Cancel = true;
         Point p = PointToScreen(ClientRectangle.Location);
         MenuWrapper.ShowMenu(menuMain, p.X, p.Y);
      }
      private void window_LocationChanged(object sender, EventArgs e)
      {
         if (WindowState == FormWindowState.Normal && Settings.Default.MainWindowLayout != WindowDockType.FloatPanel)
         {
            Settings.Default.MainWindowRect = Bounds;
         }
      }
      private void window_Closing(object sender, FormClosingEventArgs e)
      {
         if (Settings.Default.MainWindowLayout != WindowDockType.FloatPanel)
         {
            Settings.Default.MainWindowRect = Bounds;
         }
      }
      private void window_WindowsThemeChanged(object sender, EventArgs e)
      {
         // HACK: AdjustProperSize() does not work here properly, asynchronous call fix it
         FDockingTimer.Interval = FDockTimerControlInterval * 10;
      }
      private void window_Deactivation(object sender, ActivationEventArgs e)
      {
         textBoxStatusMessage_Leave(null, null);
      }
      private void session_Closed(object sender, EventArgs e)
      {
         IMediaSession session = (IMediaSession)sender;
         menuSessions.Items.RemoveByKey(session.Gsid);

         DataItem item = itemViewControl["SessionsView", session.Gsid];
         if (item != null) item.View.RemoveItem(item, true, null);

         itemSessions.Enabled = menuItemSessions.Enabled = menuSessions.Items.Count > 0;
      }
      private void session_Activated(object sender, EventArgs e)
      {
         IMediaSession session = sender as IMediaSession;

         if (menuSessions.Items.ContainsKey(session.Gsid))
         {
            ToolStripMenuItem menuItem = menuSessions.Items[session.Gsid] as ToolStripMenuItem;

            if (menuItem != null)
            {
               foreach (ToolStripItem item in menuSessions.Items)
               {
                  if (item is ToolStripMenuItem) (item as ToolStripMenuItem).Checked = false;
               }
               menuItem.Checked = true;
            }
         }

         IItemView entry = itemViewControl["SessionsView"];
         if (entry != null) entry.SelectedItem = entry[session.Gsid];

         itemSessions.Enabled = menuItemSessions.Enabled = menuSessions.Items.Count > 0;
      }
      private void session_ParticipantsChanged(object sender, ParticipantsChangedEventArgs e)
      {
         IMediaSession session = (IMediaSession)sender;
         menuSessions.Items[session.Gsid].Text = session.Caption;

         DataItem item = itemViewControl["SessionsView", session.Gsid];
         if (item != null) item.Text = session.Caption;
      }
      private void session_ParamsChanged(object sender, PropertyChangedEventArgs e)
      {
         IMediaSession session = (IMediaSession)sender;

         if (e.PropertyName == "Subject")
         {
            DataItem item = itemViewControl["SessionsView", session.Gsid];
            if (item != null) item.Text = session.Caption;
         }
      }
      private void communicator_ProfileLoaded(object sender, EventArgs e)
      {
         OrganizeProfileView();
      }
      private void communicator_AccountAdded(object sender, AccountAddedEventArgs e)
      {
         ToolStripMenuItem item = new ToolStripMenuItem(e.Account.ToString(InfoStrings.NameServiceStatus),
                                      null, itemSelectAccount_Click, e.Account.Identifier);
         menuProfile.Items.Insert(0, item);
         item.Checked = e.Account == FCommunicator.CurrentAccount;
         item.Tag = e.Account;
      }
      private void communicator_StatusChanged(object sender, StatusChangedEventArgs e)
      {
         if (e == null || e.Account == FCommunicator.CurrentAccount)
         {
            Account account = FCommunicator.CurrentAccount;
            labelStatusMessage.Text = account.StatusMessage;
            statusBarLabel.Text = account.ToString(InfoStrings.NameServiceStatus);
            statusBarImage.Image = ResourceWrapper.GetImage("Status" + account.Status.Value.ToString());
         }
      }
      private void communicator_AccountRemoved(object sender, AccountRemovedEventArgs e)
      {
         ToolStripItem item = menuProfile.Items[e.Account.Identifier];

         if (item == null) return;

         menuProfile.Items.Remove(item);
         item.Dispose();
      }
      private void communicator_ContactsLoaded(object sender, ContactsLoadedEventArgs e)
      {
         ItemView view = GetContactsView(e.Owner);

         if (view != null) ComposeContactsView(view.Tag as Account);
      }
      private void communicator_ContactsChanged(object sender, ContactsChangedEventArgs e)
      {
         ItemView view = GetContactsView(e.Owner);

         if (view == null) return;

         try
         {
            FComposeContactsDenied = true;

            DataItem item = null;

            if ((e.Actions & ContactsChangedActions.Add) == ContactsChangedActions.Add)
            {
               if (e.Contact != null)
               {
                  if (Settings.Default.ShowGroups)
                  {
                     if (view[e.Group.Name] == null) view.AddGroup(e.Group.Name, "", e.Group.Name, "", null, e.Group);
                     item = view.AddItem(e.Contact.Identifier, e.Group.Name, e.Contact.CustomName, e.Contact.Status.ToShortString(), "Status:" + e.Contact.Status.Value.ToString(), e.Contact);
                  }
                  else
                  {
                     item = view.AddItem(e.Contact.Identifier, e.Owner.RootGroup.Name, e.Contact.CustomName, e.Contact.Status.ToShortString(), "Status:" + e.Contact.Status.Value.ToString(), e.Contact);
                  }
                  UpdateContactGroups(view, e.Contact.Groups);
               }
               else if (e.Group != null && (Settings.Default.ShowGroups || e.Group.IsSystem))
               {
                  item = view.AddGroup(e.Group.Name, e.Group.ParentName, e.Group.Name, "", null, e.Group);
               }
            }
            else if ((e.Actions & ContactsChangedActions.Move) == ContactsChangedActions.Move)
            {
               if (e.ActionSource != ActionSource.User && e.Contact != null)
               {
                  item = view[e.Contact.Identifier];
                  DataItem newParent = view[e.Contact.Group.Name];

                  view.MoveItem(item, newParent, DropResults.Auto);
               }
               UpdateContactGroups(view, null);
            }
            else if ((e.Actions & ContactsChangedActions.Remove) == ContactsChangedActions.Remove)
            {
               if (e.Contact != null)
               {
                  item = view[e.Contact.Identifier];
                  if (item != null)
                  {
                     view.RemoveItem(item, true, null);
                     UpdateContactsViewHeader();
                     UpdateContactGroups(view, e.Contact.Groups);
                  }
               }
               else if (e.Group != null)
               {
                  item = view[e.Group.Name];
                  if (item != null)
                  {
                     view.RemoveItem(item, false, item.Parent);
                     UpdateContactsViewHeader();
                  }
               }
            }
            else if ((e.Actions & ContactsChangedActions.Hide) == ContactsChangedActions.Hide)
            {
               if (e.Contact != null)
               {
                  item = view[e.Contact.Identifier];
                  if (item == null) return;

                  item.Hidden = true;
                  if (Settings.Default.ShowHiddenContacts) UpdateDataItem(item); else view.RemoveItem(item, true, null);
               }
            }
            else if ((e.Actions & ContactsChangedActions.Modify) == ContactsChangedActions.Modify)
            {
               if (e.Contact != null)
               {
                  item = view[e.Contact.Identifier];
                  if (item == null) return;

                  item.Hidden = !e.Contact.Visible;
                  UpdateDataItem(item);
               }
               else if (e.Group != null)
               {
                  if (e.Name != e.Group.Name)
                  {
                     item = view[e.Name];

                     if (item != null)
                     {
                        view.RenameItem(item, e.Group.Name);
                        UpdateDataItem(item);
                     }
                  }
               }
            }
         }
         finally
         {
            FComposeContactsDenied = false;
         }
      }
      private void communicator_PropertyChanged(object sender, PropertyChangedEventArgs e)
      {
         if (e.PropertyName == "ColorTheme") ColorTheme = FCommunicator.ColorTheme;
         else if (e.PropertyName == "RenderMode") RenderMode = FCommunicator.RenderMode;
         else if (e.PropertyName == "Userpic")
         {
            if (panelUserpic.BackgroundImage != null) panelUserpic.BackgroundImage.Dispose();
            panelUserpic.BackgroundImage = FCommunicator.CurrentAccount.Info.Userpic;
         }
      }
      private void communicator_CurrentAccountChanged(object sender, PropertyChangedEventArgs e)
      {
         ShowAccount(FCommunicator.CurrentAccount);
      }
      private void communicator_MediaSessionTypeAdded(object sender, MediaSessionTypeAddedEventArgs e)
      {
         AddCreateSessionMenuItem(e.TypeInfo);
      }
      private void communicator_MessageAccepted(object sender, MessageAcceptedEventArgs e)
      {
         IItemView entry = GetContactsView((Account)e.Message.Recipient);
         DataItem item = entry != null ? entry[e.Message.Sender.Identifier] : null;

         if (item != null)
         {
            Contact contact = (Contact)e.Message.Sender;
            item.ImageName = "Status:" + contact.Status.Value.ToString();
            item.Comment = contact.Status.ToShortString();
            item[typeof(ServiceMessage)] = null;
         }
      }
      private void communicator_MediaSessionCreated(object sender, EventArgs e)
      {
         IMediaSession session = (IMediaSession)sender;

         session.Closed += new EventHandler(session_Closed);
         session.Activated += new EventHandler(session_Activated);
         session.ParamsChanged += new PropertyChangedEventHandler(session_ParamsChanged);
         session.ParticipantsChanged += new EventHandler<ParticipantsChangedEventArgs>(session_ParticipantsChanged);

         string caption = session.Caption;

         ToolStripMenuItem item = new ToolStripMenuItem(caption, null, (object s, EventArgs a) =>
         {
            ToolStripItem it = s as ToolStripItem;
            FCommunicator.ShowMediaSession(it.Tag as ChatSession, TargetWindow.Existing);
         }, session.Gsid);

         menuSessions.Items.Add(item);
         item.Tag = session;

         if (FCreateSessionView)
         {
            ItemView view = itemViewControl["SessionsView"];

            if (view == null)
            {
               view = AddItemView("SessionsView", "Sessions", "Sessions", ViewStyle.Tree);
               view.NodeSelectionType = NodeSelectionType.FullRow;
               view.ShowFocusRectangle = false;
               view.Margin = new Padding(1);
               view.AllowDrag = false;
            }

            string typeTag = (session.Visualizer == null ? session.GetType().Name : session.Visualizer.SessionTypeTag) + " sessions";

            DataItem group = view[typeTag];

            if (group == null) group = view.AddGroup(typeTag, "", typeTag, "", null, null);

            view.AddItem(session.Gsid, group, caption, "", "SayingBubbleBlue", session);

            view.SelectedItem = null;
         }
      }
      private void itemManageProfile_Click(object sender, EventArgs e)
      {
         FCommunicator.ShowSettings("Profile");
      }
      private void itemImportProfile_Click(object sender, EventArgs e)
      {
         FCommunicator.ImportProfile(null);
      }
      private void itemAddAccount_Click(object sender, EventArgs e)
      {
         FCommunicator.ShowAddAccount();
      }
      private void itemLogonAs_Click(object sender, EventArgs e)
      {
         FCommunicator.ShowLogonWindow(null);
      }
      private void itemRemoveAccount_Click(object sender, EventArgs e)
      {
         FCommunicator.ShowRemoveAccount(FCommunicator.CurrentAccount, false);
      }
      private void itemSelectAccount_Click(object sender, EventArgs e)
      {
         ToolStripMenuItem item = (ToolStripMenuItem)sender;

         FCommunicator.CurrentAccount = (Account)item.Tag;
      }
      private void itemDockWindow_Click(object sender, EventArgs e)
      {
         if (sender == itemClassicWindowLarge)
         {
            Settings.Default.MainWindowLayout = WindowDockType.ClassicWindowLarge;
         }
         else if (sender == itemClassicWindowNormal)
         {
            Settings.Default.MainWindowLayout = WindowDockType.ClassicWindowNormal;
         }
         else if (sender == itemFloatingPanel)
         {
            Settings.Default.MainWindowLayout = WindowDockType.FloatPanel;
         }
      }
      private void itemWindowDockSide_Click(object sender, EventArgs e)
      {
         Settings.Default.MainWindowLeftSide = sender == itemViewLeftSide;
      }
      private void itemRenderMode_MouseEnter(object sender, EventArgs e)
      {
         FCommunicator.RenderMode = sender == itemRenderModeSystem ? ToolStripRenderMode.System : ToolStripRenderMode.Professional;
      }
      private void itemRenderMode_Click(object sender, EventArgs e)
      {
         Settings.Default.RenderMode = sender == itemRenderModeSystem ? ToolStripRenderMode.System.ToString() : ToolStripRenderMode.Professional.ToString();
      }
      private void itemShowSystemBorder_Click(object sender, EventArgs e)
      {
         if (Settings.Default.MainWindowLayout == WindowDockType.FloatPanel) WindowBorders = !WindowBorders;
      }
      private void itemShowToolBar_Click(object sender, EventArgs e)
      {
         if (sender == itemShowMenuBar)
         {
            Settings.Default.ShowMainWindowMenuBar = !Settings.Default.ShowMainWindowMenuBar;
         }
         else if (sender == itemShowAccountBar)
         {
            Settings.Default.ShowAccountBar = !Settings.Default.ShowAccountBar;
         }
         else if (sender == itemShowTopToolbar)
         {
            Settings.Default.ShowMainWindowTopToolbar = !Settings.Default.ShowMainWindowTopToolbar;
         }
         else if (sender == itemShowBottomToolbar)
         {
            Settings.Default.ShowMainWindowBottomToolbar = !Settings.Default.ShowMainWindowBottomToolbar;
         }
      }
      private void itemContactsView_Click(object sender, EventArgs e)
      {
         ToolStripMenuItem item = (ToolStripMenuItem)sender;

         if (sender == itemShowGroups)
         {
            Settings.Default.ShowGroups = !Settings.Default.ShowGroups;
         }
         else if (sender == itemShowHiddenContacts)
         {
            Settings.Default.ShowHiddenContacts = !Settings.Default.ShowHiddenContacts;
         }
         else if (sender == itemShowOfflineContacts)
         {
            Settings.Default.ShowOfflineContacts = !Settings.Default.ShowOfflineContacts;
         }
      }
      private void itemCreateGroup_Click(object sender, EventArgs e)
      {
         FCommunicator.ShowAddContactGroup("", FCommunicator.CurrentAccount);
      }
      private void itemMoreOptions_Click(object sender, EventArgs e)
      {
         FCommunicator.ShowSettings("General");
      }
      private void itemAddContact_Click(object sender, EventArgs e)
      {
         FCommunicator.ShowAddContact(null, false);
      }
      private void itemFindPerson_Click(object sender, EventArgs e)
      {
         FCommunicator.ShowPeopleSearch(true);
      }
      private void itemPeopleSearch_Click(object sender, EventArgs e)
      {
         FCommunicator.ShowPeopleSearch(false);
      }
      private void itemAccountProperties_Click(object sender, EventArgs e)
      {
         FCommunicator.ShowUserProperties(FCommunicator.CurrentAccount, null);
      }
      private void itemSystemLog_Click(object sender, EventArgs e)
      {
         FCommunicator.ShowEventViewer();
      }
      private void itemStatus_Click(object sender, EventArgs e)
      {
         Status status = FCommunicator.CurrentAccount.Status;
         status.AutoTrack = false;
         status.Value = (StatusCodes)Enum.Parse(typeof(StatusCodes), (sender as ToolStripItem).Tag.ToString());
         FCommunicator.NotifyPresence(FCommunicator.CurrentAccount, null, status);
      }
      private void itemGlobalStatus_Click(object sender, EventArgs e)
      {
         Status status = Status.Offline;
         status.AutoTrack = false;
         status.Value = (StatusCodes)Enum.Parse(typeof(StatusCodes), (sender as ToolStripItem).Tag.ToString());
         FCommunicator.NotifyPresence(null, null, status);
      }
      private void itemWebsite_Click(object sender, EventArgs e)
      {
         if (sender == itemOurWebsite)
         {
            Shell.OpenLink(Settings.Default.BaseUrl);
         }
         else if (sender == itemJoinUs)
         {
            Shell.OpenLink(Settings.Default.BaseUrl + Settings.Default.UrlJoinus);
         }
      }
      private void itemAbout_Click(object sender, EventArgs e)
      {
         InternetCommunicator.Self.About();
      }
      private void itemExit_Click(object sender, EventArgs e)
      {
         FCommunicator.Shutdown(true);
      }
      private void itemApplyStylesToMenus_Click(object sender, EventArgs e)
      {
         Settings.Default.ApplyStylesToMenus = !Settings.Default.ApplyStylesToMenus;
      }
      private void itemTheme_Click(object sender, EventArgs e)
      {
         ColorTheme theme = (sender as ToolStripMenuItem).Tag as ColorTheme;

         Settings.Default.ColorTheme = theme == null ? "" : theme.Name;
         Settings.Default.ApplyStylesToMenus = FCommunicator.ColorTheme != null;
      }
      private void itemTheme_MouseEnter(object sender, EventArgs e)
      {
         FCommunicator.ColorTheme = (sender as ToolStripMenuItem).Tag as ColorTheme;
      }
      private void view_ItemRemoving(object sender, ItemViewRemovingEventArgs e)
      {
         e.Cancel = true;

         if (e.Item[typeof(Contact)] is Contact)
         {
            FCommunicator.ShowRemoveContact(e.Item[typeof(Contact)] as Contact);
         }
      }
      private void view_ItemMoving(object sender, ItemViewMovingEventArgs e)
      {
         e.Cancel = e.Item.IsGroup;
      }
      private void view_ItemMoved(object sender, ItemViewMovedEventArgs e)
      {
         Contact contact = e.Item[typeof(Contact)] as Contact;

         if (contact != null && e.OldParent != e.Item.Parent)
         {
            ContactGroup parent = e.Item.Parent != null ? e.Item.Parent[typeof(ContactGroup)] as ContactGroup : null;

            if (parent == null) parent = contact.Owner.DefaultGroup;

            FCommunicator.SaveAccountData(contact.Owner, SaveAccountActions.MoveContact, contact, parent, ActionSource.User);
            FCommunicator.SaveContacts();

            if (e.OldParent != null) UpdateDataItem(e.OldParent);
            if (e.Item.Parent != null) UpdateDataItem(e.Item.Parent);
         }
      }
      private void view_ItemHover(object sender, ItemViewBasicEventArgs e)
      {
         //if (e.Item[typeof(Contact)] is Contact)
         //{
         //   Contact contact = e.Item[typeof(Contact)] as Contact;
         //   toolTipUser.ToolTipTitle = Resources.S_User_details.Replace("<user>", contact.CustomName);
         //   toolTipUser.Show(contact.XObject.ToString(), this, -150, PointToClient(Cursor.Position).Y, 2000);
         //}
      }
      private void view_HeaderPaint(object sender, PaintEventArgs e)
      {
         FCommunicator.DrawTheme(ColorTheme, e.Graphics, (sender as Control).ClientRectangle, ColorThemeObject.Header2);
      }
      private void view_ItemsCompare(object sender, ItemsCompareEventArgs e)
      {
         ContactsSortStyle sortBy = Settings.Default.ContactsSortStyle;

         if (e.Item1[typeof(Contact)] is Contact && e.Item2[typeof(Contact)] is Contact)
         {
            Contact contact1 = e.Item1[typeof(Contact)] as Contact;
            Contact contact2 = e.Item2[typeof(Contact)] as Contact;

            if (contact1.Status.Value != StatusCodes.Offline &&
                     contact2.Status.Value == StatusCodes.Offline)
            {
               e.CompareResult = -1;
            }
            else if (contact1.Status.Value == StatusCodes.Offline &&
                     contact2.Status.Value != StatusCodes.Offline)
            {
               e.CompareResult = +1;
            }
            else if (sortBy == ContactsSortStyle.CaptionWidth)
            {
               e.CompareResult = StringExt.CompareWidth(e.Item1.Text, e.Item2.Text, e.Item1.View.Font);
            }
            else
            {
               e.CompareResult = string.Compare(e.Item1.Text, e.Item2.Text);
            }
         }
         else if (e.Item1[typeof(ContactGroup)] is ContactGroup && e.Item2[typeof(ContactGroup)] is ContactGroup)
         {
            ContactGroup group1 = e.Item1[typeof(ContactGroup)] as ContactGroup;
            ContactGroup group2 = e.Item2[typeof(ContactGroup)] as ContactGroup;

            if (sortBy == ContactsSortStyle.CaptionWidth)
            {
               e.CompareResult = StringExt.CompareWidth(group1.Name, group2.Name, e.Item1.View.Font);
            }
            else if (group1.SortTag > 0 && group2.SortTag > 0)
            {
               e.CompareResult = group1.SortTag - group2.SortTag;
            }
            else
            {
               e.CompareResult = string.Compare(group1.Name, group2.Name);
            }
         }
         else if (e.Item1[typeof(Contact)] is Contact && e.Item2[typeof(ContactGroup)] is ContactGroup)
         {
            e.CompareResult = -1;
         }
         else if (e.Item1[typeof(ContactGroup)] is ContactGroup && e.Item2[typeof(Contact)] is Contact)
         {
            e.CompareResult = +1;
         }
      }
      private void view_ItemExpandedCollapsed(object sender, ItemViewExpandedCollapsedEventArgs e)
      {
         if (e.ByUser) SaveExpandedState(e.Item.View);
      }
      private void view_MouseDown(object sender, MouseEventArgs e)
      {
         ItemView viewEntry = (ItemView)sender;

         if (viewEntry.SelectedItem == null && e.Button == MouseButtons.Right)
         {
            if (viewEntry == GetContactsView(null))
            {
               MenuWrapper.ShowMenu(menuContacts);
            }
            else
            {
               MenuWrapper.ShowMenu(menuCreateSession);
            }
         }
      }
      private void view_ItemContextMenu(object sender, ItemViewBasicEventArgs e)
      {
         if (e.Item != null)
         {
            MediaSession session = (MediaSession)e.Item[typeof(MediaSession)];
            if (session != null)
            {
               FCommunicator.ShowSessionMenu(session);
               return;
            }
            Contact contact = (Contact)e.Item[typeof(Contact)];
            if (contact != null)
            {
               FCommunicator.ShowUserMenu(contact);
               return;
            }
            ContactGroup group = (ContactGroup)e.Item[typeof(ContactGroup)];
            if (group != null)
            {
               FCommunicator.ShowContactGroupMenu(group);
               return;
            }
         }
      }
      private void view_ItemActivated(object sender, ItemViewBasicEventArgs e)
      {
         ActivateContactListItem(e.Item);
      }
      private void view_ItemSelected(object sender, ItemViewBasicEventArgs e)
      {
         MediaSession session = (MediaSession)e.Item[typeof(MediaSession)];

         if (session == null || session.Visualizer == null || session.Visualizer.MediaWindow == null) return;

         session.Visualizer.MediaWindow.ActiveMediaSession = session;
      }
      private void menuThemes_MouseLeave(object sender, EventArgs e)
      {
         FCommunicator.ColorFillStyle = Settings.Default.ColorFillStyle;
         FCommunicator.RenderMode = (ToolStripRenderMode)Enum.Parse(typeof(ToolStripRenderMode), Settings.Default.RenderMode);
         FCommunicator.ColorTheme = FCommunicator.ColorThemes.Contains(Properties.Settings.Default.ColorTheme) ? FCommunicator.ColorThemes[Properties.Settings.Default.ColorTheme] : null;
      }
      private void labelAccountName_MouseDown(object sender, MouseEventArgs e)
      {
         if (e.Button == MouseButtons.Left)
         {
            ShowAccountBar = !ShowAccountBar;
         }
         else
         {
            FCommunicator.ShowUserMenu(FCommunicator.CurrentAccount);
         }
      }
      private void statusBarLabel_MouseUp(object sender, MouseEventArgs e)
      {
         Padding p = statusBarLabel.Margin;

         if (Environment.OSVersion.Version.Major == 6)
         {
            p.Top = 2;
            p.Bottom = 1;
         }
         else
         {
            p.Top = 1;
            p.Bottom = 0;
         }
         statusBarLabel.Margin = p;

         if (e.Button == MouseButtons.Left)
         {
            MenuWrapper.ShowMenu(menuPresence);
         }
         else if (e.Button == MouseButtons.Right)
         {
            MenuWrapper.ShowMenu(menuMain);
         }
      }
      private void statusBarLabel_MouseDown(object sender, MouseEventArgs e)
      {
         Padding p = statusBarLabel.Margin;
         if (Environment.OSVersion.Version.Major == 6)
         {
            p.Top = 3;
            p.Bottom = 0;
         }
         else
         {
            p.Top = 2;
            p.Bottom = -1;
         }
         statusBarLabel.Margin = p;
      }
      private void statusBarImage_MouseUp(object sender, MouseEventArgs e)
      {
         MenuWrapper.ShowMenu(menuGlobalPresence);
      }
      private void labelUserpic_Click(object sender, EventArgs e)
      {
         if (FCommunicator.ShowUserpicDialog())
         {
            FCommunicator.CurrentAccount.ServiceDriver.SaveAccountData(FCommunicator.CurrentAccount, SaveAccountActions.UploadUserpic);
         }
      }
      private void panelUserpic_BackgroundImageChanged(object sender, EventArgs e)
      {
         labelUserpic.Text = panelUserpic.BackgroundImage == null ? Resources.S_Setup_userpic : "";

         if (panelUserpic.BackgroundImage == null) panelUserpic.BackgroundImage = FCommunicator.DefaultUserpic;
         else if (panelUserpic.BackgroundImage != FCommunicator.DefaultUserpic) ShowAccountBar = Settings.Default.ShowAccountBar;
      }
      private void toolTipUser_Popup(object sender, PopupEventArgs e)
      {
         e.ToolTipSize = new Size(150, 200);
      }
      private void toolStrip_Paint(object sender, PaintEventArgs e)
      {
         FCommunicator.DrawTheme(ColorTheme, e.Graphics, (sender as Control).ClientRectangle,
            Settings.Default.ShowMainWindowMenuBar && sender == toolStripTop ? ColorThemeObject.ToolStripWithAppMenu : ColorThemeObject.ToolStrip);
      }
      private void controlButton_Paint(object sender, PaintEventArgs e)
      {
         ToolStripDropDownButton button = (ToolStripDropDownButton)sender;

         if (button == buttonProfile)
         {
            //e.Graphics.DrawImageUnscaled(button.Selected || button.Pressed ? FDropDownArrowImage1 : FDropDownArrowImage2, 2, 10);
            //e.Graphics.DrawImageUnscaled(button.Image, 12, 3);
            e.Graphics.DrawImageUnscaled(button.Image, 3, 3);
            e.Graphics.DrawImageUnscaled(button.Selected || button.Pressed ? FDropDownArrowImage1 : FDropDownArrowImage2, 23, 10);
         }
         else if (button == buttonMenu)
         {
            //e.Graphics.DrawString(InternetCommunicator.ProjectName, labelAccount.Font, Brushes.DarkSlateGray, 21, 5);
            e.Graphics.DrawImageUnscaled(button.Image, 3, 3);
            e.Graphics.DrawImageUnscaled(button.Selected || button.Pressed ? FDropDownArrowImage1 : FDropDownArrowImage2, 23, 10);
         }
         else if (button == buttonContactList)
         {
            //e.Graphics.DrawImageUnscaled(button.Selected || button.Pressed ? FDropDownArrowImage1 : FDropDownArrowImage2, 2, 10);
            //e.Graphics.DrawImageUnscaled(button.Image, 12, 4);
            e.Graphics.DrawImageUnscaled(button.Image, 4, 4);
            e.Graphics.DrawImageUnscaled(button.Selected || button.Pressed ? FDropDownArrowImage1 : FDropDownArrowImage2, 24, 10);
         }
         else if (button == buttonServiceMenu)
         {
            //e.Graphics.DrawImageUnscaled(button.Selected || button.Pressed ? FDropDownArrowImage1 : FDropDownArrowImage2, 2, 10);
            //e.Graphics.DrawImageUnscaled(button.Image, 12, 4);
            e.Graphics.DrawImageUnscaled(button.Image, 4, 4);
            e.Graphics.DrawImageUnscaled(button.Selected || button.Pressed ? FDropDownArrowImage1 : FDropDownArrowImage2, 23, 10);
         }
         else if (button == buttonPresence)
         {
            e.Graphics.DrawImageUnscaled(button.Selected || button.Pressed ? FDropDownArrowImage1 : FDropDownArrowImage2, 2, 10);
            e.Graphics.DrawImageUnscaled(button.Image, 14, 5);
            //e.Graphics.DrawImageUnscaled(button.Image, 2, 3);
            //e.Graphics.DrawImageUnscaled(button.Selected || button.Pressed ? FDropDownArrowImage1 : FDropDownArrowImage2, 23, 10);
         }
      }
      private void menuAppMain_Paint(object sender, PaintEventArgs e)
      {
         FCommunicator.DrawTheme(ColorTheme, e.Graphics, (sender as Control).ClientRectangle,
            Settings.Default.ShowMainWindowTopToolbar ? ColorThemeObject.AppMenuWithToolStrip : ColorThemeObject.AppMenu);
      }
      private void statusBar_Paint(object sender, PaintEventArgs e)
      {
         InternetCommunicator.Self.DrawTheme(ColorTheme, e.Graphics, (sender as Control).ClientRectangle, ColorThemeObject.StatusStrip);
         InternetCommunicator.Self.DrawStatusBar(ColorTheme, sender as StatusStrip, e.Graphics);
      }
      private void menu_Paint(object sender, PaintEventArgs e)
      {
         FCommunicator.DrawTheme(ColorTheme, e.Graphics, (sender as Control).ClientRectangle, ColorThemeObject.Menu);
      }
      private void menu_Opening(object sender, CancelEventArgs e)
      {
         ContextMenuStrip menu = (ContextMenuStrip)sender;

         if (menu == menuContacts)
         {
            itemFindPerson.Enabled = FCommunicator.CurrentAccount.ServiceConfig.SupportsFeature(ServiceFeatures.FindPerson);
            itemPeopleSearch.Enabled = FCommunicator.CurrentAccount.ServiceConfig.SupportsFeature(ServiceFeatures.PeopleSearch);
            itemCreateGroup.Enabled = Settings.Default.ShowGroups && FCommunicator.CurrentAccount.ServiceConfig.SupportsFeature(ServiceFeatures.AddGroup);
         }
         else if (menu == menuProfile)
         {
            foreach (ToolStripItem item in menuProfile.Items)
            {
               if (item.Tag is Account)
               {
                  item.Text = (item.Tag as Account).ToString(InfoStrings.NameServiceStatus);
                  (item as ToolStripMenuItem).Checked = item.Tag == FCommunicator.CurrentAccount;
               }
            }
         }
         else if (menu == menuFillStyles)
         {
            itemApplyStylesToMenus.Checked = Settings.Default.ApplyStylesToMenus;
         }
         else if (menu == menuLayout)
         {
            itemClosurePanel.Checked = false;
            itemEmbeddedPanel.Checked = false;
            itemFloatingPanel.Checked = Settings.Default.MainWindowLayout == WindowDockType.FloatPanel;
            itemClassicWindowLarge.Checked = Settings.Default.MainWindowLayout == WindowDockType.ClassicWindowLarge;
            itemClassicWindowNormal.Checked = Settings.Default.MainWindowLayout == WindowDockType.ClassicWindowNormal;

            itemViewLeftSide.Checked = Settings.Default.MainWindowLeftSide;
            itemViewRightSide.Checked = !Settings.Default.MainWindowLeftSide;
         }
         else if (menu == menuView)
         {
            itemShowMenuBar.Checked = Settings.Default.ShowMainWindowMenuBar;
            itemShowTopToolbar.Checked = Settings.Default.ShowMainWindowTopToolbar;
            itemShowBottomToolbar.Checked = Settings.Default.ShowMainWindowBottomToolbar;
         }
         else if (menu == menuContactsView)
         {
            itemShowGroups.Checked = Settings.Default.ShowGroups;
            itemShowHiddenContacts.Checked = Settings.Default.ShowHiddenContacts;
            itemShowOfflineContacts.Checked = Settings.Default.ShowOfflineContacts;
         }
         else if (menu == menuGlobalPresence)
         {
            itemAccountPresence.Visible = toolStripSeparator1.Visible = FCommunicator.ActiveAccounts.Count > 1;
            itemAccountPresence.Text = FCommunicator.CurrentAccount.ToString(InfoStrings.NameService);
         }

         MenuWrapper.MakeFadeEffect(menu, FCommunicator.MaxMenuOpacity);
      }
      private void panelInfoBar_Paint(object sender, PaintEventArgs e)
      {
         FCommunicator.DrawTheme(ColorTheme, e.Graphics, (sender as Control).ClientRectangle, ColorThemeObject.Area);
      }
      private void labelStatusMessage_Click(object sender, EventArgs e)
      {
         DelayedAction.Do(() =>
         {
            if (textBoxStatusMessage.Tag == null)
            {
               textBoxStatusMessage.Visible = true;
               labelStatusMessage.Visible = false;
               textBoxStatusMessage.Dock = DockStyle.Fill;
               textBoxStatusMessage.BringToFront();
               textBoxStatusMessage.Text = (FCommunicator.CurrentAccount.Status.IsAway() ?
                  (labelStatusMessage.Text == Resources.S_Enter_your_away_message_here) :
                  (labelStatusMessage.Text == Resources.S_Enter_your_greeting_text_here)) ? "" : labelStatusMessage.Text;
               textBoxStatusMessage.Select();
               textBoxStatusMessage.SelectAll();
            }
            textBoxStatusMessage.Tag = null;
         },
         labelStatusMessage.Text.Contains("http://") ? 1 : 0);
      }
      private void labelStatusMessage_TextChanged(object sender, EventArgs e)
      {
         if (labelStatusMessage.Text == "")
         {
            labelStatusMessage.Text = FCommunicator.CurrentAccount.Status.IsAway() ?
                                       Resources.S_Enter_your_away_message_here :
                                       Resources.S_Enter_your_greeting_text_here;
         }
         else
         {
            labelStatusMessage.Links.Clear();

            if (labelStatusMessage.Text.Contains("http://"))
            {
               foreach (string url in Utils.ExtractLinks(labelStatusMessage.Text))
               {
                  LinkLabel.Link link = new LinkLabel.Link(labelStatusMessage.Text.IndexOf(url), url.Length, url);
                  labelStatusMessage.Links.Add(link);
               }
            }
         }
      }
      private void textBoxStatusMessage_Leave(object sender, EventArgs e)
      {
         textBoxStatusMessage.Visible = false;
         labelStatusMessage.Visible = true;
      }
      private void labelStatusMessage_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
      {
         if (e.Button == MouseButtons.Left)
         {
            textBoxStatusMessage.Tag = "1";
            Shell.OpenLink(e.Link.LinkData.ToString());
         }
      }
      private void settings_PropertyChanged(object sender, PropertyChangedEventArgs e)
      {
         if (e.PropertyName == "MainWindowLayout" ||
             e.PropertyName == "MainWindowLeftSide")
         {
            if (Settings.Default.MainWindowLayout == WindowDockType.FloatPanel)
            {
               DockAsFloatPanel();
            }
            else
            {
               DockAsNormalWindow();
            }
         }
         else if (e.PropertyName == "ShowAccountBar")
         {
            ShowAccountBar = Settings.Default.ShowAccountBar;
         }
         else if (e.PropertyName == "ContactsSortStyle")
         {
            foreach (Account account in FCommunicator.ActiveAccounts)
            {
               ItemView view = GetContactsView(account);
               if (view != null) view.Sort();
            }
         }
         else if (e.PropertyName == "ShowGroups" ||
                  e.PropertyName == "ShowHiddenContacts" ||
                  e.PropertyName == "ShowOfflineContacts")
         {
            if (!FComposeContactsDenied)
            {
               foreach (Account account in FCommunicator.ActiveAccounts)
               {
                  ItemView view = GetContactsView(account);
                  if (view != null) ComposeContactsView(account);
               }
            }
         }
      }
      private void toolStripLabel_MouseEnter(object sender, EventArgs e)
      {
         ToolStripLabel label = sender as ToolStripLabel;
         label.Font = FLabelFontU;
         label.ForeColor = label.ActiveLinkColor;
         Cursor = Cursors.Hand;
      }
      private void toolStripLabel_MouseLeave(object sender, EventArgs e)
      {
         ToolStripLabel label = sender as ToolStripLabel;
         label.Font = FLabelFont;
         label.ForeColor = label.LinkColor;
         Cursor = Cursors.Default;
      }
      private void toolStrip_MouseUp(object sender, MouseEventArgs e)
      {
         if (e.Button == MouseButtons.Right)
         {
            MenuWrapper.ShowMenu(menuView);
         }
      }
      private void toolStrip_EnabledChanged(object sender, EventArgs e)
      {
         ToolStrip ts = sender as ToolStrip;

         ControlEffects.Slide(ts.Parent, ts.Enabled ? SlideAction.Expand : SlideAction.Collapse, false, e != null,
                  (action) => itemViewControl.SuspendLayout(), (action) => itemViewControl.ResumeLayout(true));

         if (sender == toolStripTop) menuItemProfile.Visible = !toolStripTop.Enabled;
      }

      #endregion
   }
}